home *** CD-ROM | disk | FTP | other *** search
Wrap
-- card: 5368 from stack: in -- bmap block id: 0 -- flags: 0000 -- background id: 2607 -- name: INTERP3D.PAS -- part contents for background part 17 ----- text ----- INTERP3D[function] PURPOSE INTERP3D performs an interpolation of the function U=U(x,y,z) defined on a 5 x 5 x 5 or larger grid using the first and second derivative terms of the three dimensional Taylor series. Derivatives are calculated using various finite-difference approximations with errors on the order of Γêåx3 andΓêåx4. The x values, y values, and the z values must be uniformly spaced, but Γêåx need not equal Γêåy or Γêåz. INTERP3D requires the passage of an X, Y, and Z array, the X,Y and Z array size a 3d U array and the points XIN,YIN,ZIN for which the interpolation is to be done. TYPE REQUIREMENTS CONST NUMX = maximum number of x data points-1; {may be larger than XSIZE} NUMY = maximum number of y data points-1; {may be larger than YSIZE} NUMZ = maximum number of z data points-1; {may be larger than ZSIZE} Type FLOAT = REAL or DOUBLE or EXTENDED; DATAX = ARRAY [0..NUMX] of FLOAT; DATAY = ARRAY [0..NUMY] of FLOAT; DATAZ = ARRAY [0..NUMZ] of FLOAT; CUBE = ARRAY [0..NUMX,0..NUMY,0..NUMZ] of FLOAT; FIXXED = INTEGER or LONGINT; CALLING PROCEDURE var X:DATAX;{Known X values} Y:DATAY;{Known Y values} Z:DATAZ;{Known Z values} U:CUBE;{Known U=U(X,Y,Z)} XSIZE,YSIZE,ZSIZE:FIXXED;{Size of X, Y, and Z array} XIN,YIN,ZIN,UOUT:FLOAT;{Input points and output point for the interpolation} DEFINE X,Y,Z and U arrays. Pick the points for interpolation XIN, YIN, and ZIN. UOUT:=INTERP2D(XIN,YIN,ZIN,X,Y,Z,U,XSIZE,YSIZE,ZSIZE); EXAMPLE The example routine defines U as U=sin(x)*cos(y)*tan(z) on a 10 X 10 X 10 grid. X,Y, and Z range from 0 to 1. Then 200 XIN,YIN and ZIN variables are picked. XIN=YIN=ZIN. The input ranges from zero to 1. As the calculation progresses, the maximum error of the interpolation which has occured is printed to the screen along with the point at which it occurs. At the end, the maximum error is reprinted. REFERENCES James, M. L., Smith, G. M., Wolford, J. C.: Applied Numerical Methods for Digital Computation With Fortran and CSMP, Harper and Row, New York, 1977. Spiegel, M. R.: Mathematical Handbook of Formulas and Tables, McGraw-Hill, New York, 1968. -- part contents for background part 22 ----- text ----- INTERP3D.PAS -- part contents for background part 23 ----- text ----- INTERP3D.PAS -- part contents for background part 26 ----- text ----- 22 -- part contents for background part 6 ----- text ----- PROGRAM TEST_3DINTERP; TYPE FLOAT = REAL; FIXXED = INTEGER; VAR I, J, K : FIXXED; XINP, YINP, ZINP, UOUT, ERR, XSAVE, MISTAKE : FLOAT; X : ARRAY[0..10] OF FLOAT; Y : ARRAY[0..10] OF FLOAT; Z : ARRAY[0..10] OF FLOAT; U : ARRAY[0..10, 0..10, 0..10] OF FLOAT; PROCEDURE see; VAR R : Rect; BEGIN HideAll; SetRect(R, 0, 35, 550, 330); SettextRect(R); Showtext; END; FUNCTION INTERP3D (XIN, YIN, ZIN : FLOAT; XSIZE, YSIZE, ZSIZE : FIXXED) : FLOAT; VAR I, J, L, K, M : FIXXED; DFDX, DFDY, DFDZ, DX, DY, DZ, D2FDXDX, D2FDYDY, D2FDZDZ : FLOAT; D2UDXDY, D2UDXDZ, D2UDYDZ, FX, FXX, FY, FYY, FZ, FZZ : FLOAT; INTER, DELX, DELY, DELZ : FLOAT; INTERP2D : FLOAT; DUDX, DUDY : ARRAY[1..5] OF FLOAT; PROCEDURE F_DUDX (I, J, K : FIXXED); BEGIN IF (I <= 1) THEN BEGIN DFDX := (-3.0 * U[(I + 4), J, K] + 16.0 * U[(I + 3), J, K]); DFDX := DFDX + (-36.0 * U[(I + 2), J, K] + 48.0 * U[(I + 1), J, K] - 25.0 * U[I, J, K]); DFDX := DFDX / (12.0 * DX) END ELSE IF (I >= (XSIZE - 1)) THEN BEGIN DFDX := (3.0 * U[(I - 4), J, K] - 16.0 * U[(I - 3), J, K]); DFDX := DFDX + (36.0 * U[(I - 2), J, K] - 48.0 * U[(I - 1), J, K] + 25.0 * U[I, J, K]); DFDX := DFDX / (12.0 * DX) END ELSE BEGIN DFDX := -U[(I + 2), J, K] + 8.0 * U[(I + 1), J, K] - 8.0 * U[(I - 1), J, K] + U[(I - 2), J, K]; DFDX := DFDX / (12.0 * DX) END END; PROCEDURE F_DUDY (I, J, K : FIXXED); BEGIN IF (J <= 1) THEN BEGIN DFDY := (-3.0 * U[I, (J + 4), K] + 16.0 * U[I, (J + 3), K] - 36.0 * U[I, (J + 2), K]); DFDY := DFDY + (48.0 * U[I, (J + 1), K] - 25.0 * U[I, J, K]); DFDY := DFDY / (12.0 * DY) END ELSE IF (J >= (YSIZE - 1)) THEN BEGIN DFDY := (3.0 * U[I, (J - 4), K] - 16.0 * U[I, (J - 3), K]); DFDY := DFDY + (36.0 * U[I, (J - 2), K] - 48.0 * U[I, (J - 1), K] + 25.0 * U[I, J, K]); DFDY := DFDY / (12.0 * DY) END ELSE BEGIN DFDY := (-U[I, (J + 2), K] + 8.0 * U[I, (J + 1), K] - 8.0 * U[I, (J - 1), K]); DFDY := DFDY + U[I, (J - 2), K]; DFDY := DFDY / (12.0 * DY) END; END; PROCEDURE F_DUDZ (I, J, K : FIXXED); BEGIN IF (K <= 1) THEN BEGIN DFDZ := (-3.0 * U[I, J, K + 4] + 16.0 * U[I, J, K + 3] - 36.0 * U[I, J, K + 2]); DFDZ := (DFDZ + (48.0 * U[I, J, K + 1] - 25.0 * U[I, J, K])) / (12.0 * DY) END ELSE IF (K >= (ZSIZE - 1)) THEN BEGIN DFDZ := (3.0 * U[I, J, K - 4] - 16.0 * U[I, J, K - 3]); DFDZ := DFDZ + (36.0 * U[I, J, K - 2] - 48.0 * U[I, J, K - 1]); DFDZ := (DFDZ + (25.0 * U[I, J, K])) / (12.0 * DY) END ELSE BEGIN DFDZ := -U[I, J, K + 2] + 8.0 * U[I, J, K + 1] - 8.0 * U[I, J, K - 1]; DFDZ := DFDZ + U[I, J, K - 2]; DFDZ := DFDZ / (12.0 * DZ) END END; PROCEDURE F_D2UDXDX (I, J, K : FIXXED); BEGIN IF (I <= 1) THEN BEGIN D2FDXDX := (70.0 * U[I, J, K] - 208.0 * U[(I + 1), J, K]); D2FDXDX := D2FDXDX + (228.0 * U[(I + 2), J, K] - 112.0 * U[(I + 3), J, K]); D2FDXDX := (D2FDXDX + 22.0 * U[(I + 4), J, K]) / (24.0 * DX * DX) END ELSE IF (I >= (XSIZE - 1)) THEN BEGIN D2FDXDX := -(-70.0 * U[I, J, K] + 208.0 * U[(I - 1), J, K]); D2FDXDX := D2FDXDX - (-228.0 * U[(I - 2), J, K]); D2FDXDX := D2FDXDX - (112.0 * U[(I - 3), J, K] - 22.0 * U[I - 4, J, K]); D2FDXDX := D2FDXDX / (24.0 * DX * DX) END ELSE BEGIN D2FDXDX := -U[(I + 2), J, K] + 16.0 * U[(I + 1), J, K] - 30.0 * U[I, J, K]; D2FDXDX := D2FDXDX + 16.0 * U[(I - 1), J, K] - U[(I - 2), J, K]; D2FDXDX := D2FDXDX / (12.0 * SQR(DX)) END END; PROCEDURE F_D2UDYDY (I, J, K : FIXXED); BEGIN IF (J <= 1) THEN BEGIN D2FDYDY := (70.0 * U[I, J, K] - 208.0 * U[I, (J + 1), K]); D2FDYDY := D2FDYDY + (228.0 * U[I, (J + 2), K] - 112.0 * U[I, (J + 3), K]); D2FDYDY := D2FDYDY + (22.0 * U[I, (J + 4), K]); D2FDYDY := D2FDYDY / (24.0 * DY * DY) END ELSE IF (J >= (YSIZE - 1)) THEN BEGIN D2FDYDY := -(-70.0 * U[I, J, K] + 208.0 * U[I, (J - 1), K]); D2FDYDY := D2FDYDY - (-228.0 * U[I, (J - 2), K] + 112.0 * U[I, (J - 3), K]); D2FDYDY := D2FDYDY - (-22.0 * U[I, (J - 4), K]); D2FDYDY := D2FDYDY / (24.0 * DY * DY) END ELSE BEGIN D2FDYDY := -U[I, (J + 2), K] + 16.0 * U[I, (J + 1), K] - 30.0 * U[I, J, K]; D2FDYDY := D2FDYDY + 16.0 * U[I, (J - 1), K] - U[I, (J - 2), K]; D2FDYDY := D2FDYDY / (12.0 * SQR(DY)) END END; PROCEDURE F_D2UDZDZ (I, J, K : FIXXED); BEGIN IF (K <= 1) THEN BEGIN D2FDZDZ := (70.0 * U[I, J, K] - 208.0 * U[I, J, K + 1]); D2FDZDZ := D2FDZDZ + (228.0 * U[I, J, K + 2] - 112.0 * U[I, J, K + 3]); D2FDZDZ := (D2FDZDZ + (22.0 * U[I, J, K + 4])) / (24.0 * DX * DX) END ELSE IF (K >= (ZSIZE - 1)) THEN BEGIN D2FDZDZ := -(-70.0 * U[I, J, K] + 208.0 * U[I, J, K - 1]); D2FDZDZ := D2FDZDZ - (-228.0 * U[I, J, K - 2] + 112.0 * U[I, J, K - 3]); D2FDZDZ := (D2FDZDZ - (-22.0 * U[I, J, K - 4])) / (24.0 * DX * DX) END ELSE BEGIN D2FDZDZ := -U[I, J, K + 2] + 16.0 * U[I, J, K + 1] - 30.0 * U[I, J, K]; D2FDZDZ := D2FDZDZ + 16.0 * U[I, J, K - 1] - U[I, J, K - 2]; D2FDZDZ := D2FDZDZ / (12.0 * SQR(DZ)) END END; BEGIN IF ((XIN <= X[XSIZE]) AND (XIN >= X[0])) THEN IF ((YIN <= Y[YSIZE]) AND (YIN >= Y[0])) THEN IF ((ZIN <= Z[ZSIZE]) AND (ZIN >= Z[0])) THEN BEGIN I := XSIZE; WHILE ((XIN <= X[I]) AND (I > 0)) DO I := I - 1; IF (ABS(XIN - X[I + 1]) < ABS(XIN - X[I])) THEN I := I + 1; J := YSIZE; WHILE ((YIN <= Y[J]) AND (J > 0)) DO J := J - 1; IF (ABS(YIN - Y[J + 1]) < ABS(YIN - Y[J])) THEN J := J + 1; K := ZSIZE; WHILE ((ZIN <= Z[K]) AND (K > 0)) DO K := K - 1; IF (ABS(ZIN - Z[K + 1]) < ABS(ZIN - Z[K])) THEN K := K + 1; DX := X[1] - X[0]; DY := Y[1] - Y[0]; DZ := Z[1] - Z[0]; INTERP2D := 0.0; F_DUDX(I, J, K); F_DUDY(I, J, K); F_DUDZ(I, J, K); F_D2UDXDX(I, J, K); F_D2UDYDY(I, J, K); F_D2UDZDZ(I, J, K); FX := DFDX; FY := DFDY; FZ := DFDZ; FXX := D2FDXDX; FYY := D2FDYDY; FZZ := D2FDZDZ; IF (J >= (YSIZE - 1)) THEN BEGIN L := 0; FOR M := J DOWNTO J - 4 DO BEGIN L := L + 1; F_DUDX(I, M, K); DUDX[L] := DFDX; END; D2UDXDY := (3.0 * DUDX[5] - 16.0 * DUDX[4]); D2UDXDY := D2UDXDY + (36.0 * DUDX[3] - 48.0 * DUDX[2] + 25.0 * DUDX[1]); D2UDXDY := D2UDXDY / (12.0 * DY) END ELSE IF (J <= 1) THEN BEGIN L := 0; FOR M := J TO J + 4 DO BEGIN L := L + 1; F_DUDX(I, M, K); DUDX[L] := DFDX; END; D2UDXDY := (-3.0 * DUDX[5] + 16.0 * DUDX[4] - 36.0 * DUDX[3]); D2UDXDY := D2UDXDY + (48.0 * DUDX[2] - 25.0 * DUDX[1]); D2UDXDY := D2UDXDY / (12.0 * DY) END ELSE BEGIN L := 0; FOR M := J - 2 TO J + 2 DO BEGIN L := L + 1; F_DUDX(I, M, K); DUDX[L] := DFDX; END; D2UDXDY := -DUDX[5] + 8.0 * DUDX[4] - 8.0 * DUDX[2] + DUDX[1]; D2UDXDY := D2UDXDY / (12.0 * DY) END END; IF (K >= (ZSIZE - 1)) THEN BEGIN L := 0; FOR M := K DOWNTO K - 4 DO BEGIN L := L + 1; F_DUDX(I, J, K); DUDX[L] := DFDX; END; D2UDXDZ := (3.0 * DUDX[5] - 16.0 * DUDX[4]); D2UDXDZ := D2UDXDZ + (36.0 * DUDX[3] - 48.0 * DUDX[2] + 25.0 * DUDX[1]); D2UDXDZ := D2UDXDZ / (12.0 * DZ) END ELSE IF (K <= 1) THEN BEGIN L := 0; FOR M := K TO K + 4 DO BEGIN L := L + 1; F_DUDX(I, J, M); DUDX[L] := DFDX END; D2UDXDZ := (-3.0 * DUDX[5] + 16.0 * DUDX[4] - 36.0 * DUDX[3]); D2UDXDZ := D2UDXDZ + (48.0 * DUDX[2] - 25.0 * DUDX[1]); D2UDXDZ := D2UDXDZ / (12.0 * DZ) END ELSE BEGIN L := 0; FOR M := K - 2 TO K + 2 DO BEGIN L := L + 1; F_DUDX(I, J, M); DUDX[L] := DFDX; END; D2UDXDZ := -DUDX[5] + 8.0 * DUDX[4] - 8.0 * DUDX[2] + DUDX[1]; D2UDXDZ := D2UDXDZ / (12.0 * DZ) END; IF (K >= (ZSIZE - 1)) THEN BEGIN L := 0; FOR M := K DOWNTO K - 4 DO BEGIN L := L + 1; F_DUDY(I, J, K); DUDY[L] := DFDY; END; D2UDYDZ := (3.0 * DUDY[5] - 16.0 * DUDY[4]); D2UDYDZ := D2UDYDZ + (36.0 * DUDY[3] - 48.0 * DUDY[2] + 25.0 * DUDY[1]); D2UDYDZ := D2UDYDZ / (12.0 * DZ) END ELSE IF (K <= 1) THEN BEGIN L := 0; FOR M := K TO K + 4 DO BEGIN L := L + 1; F_DUDY(I, J, M); DUDY[L] := DFDY; END; D2UDYDZ := (-3.0 * DUDY[5] + 16.0 * DUDY[4] - 36.0 * DUDY[3]); D2UDYDZ := D2UDYDZ + (48.0 * DUDY[2] - 25.0 * DUDY[1]); D2UDYDZ := D2UDYDZ / (12.0 * DZ) END ELSE BEGIN L := 0; FOR M := K - 2 TO K + 2 DO BEGIN L := L + 1; F_DUDY(I, J, M); DUDY[L] := DFDY; END; D2UDYDZ := -DUDY[5] + 8.0 * DUDY[4] - 8.0 * DUDY[2] + DUDY[1]; D2UDYDZ := D2UDYDZ / (12.0 * DZ); END; DX := X[0] - X[1]; DY := Y[0] - Y[1]; DZ := Z[0] - Z[1]; DELX := XIN - X[I]; DELY := YIN - Y[J]; DELZ := ZIN - Z[K]; INTER := U[I, J, K] + DELX * FX + DELY * FY + DELX * DELX * FXX / 2.0; INTER := INTER + DELY * DELY * FYY / 2.0; INTERP2D := INTER + DELX * DELY * D2UDXDY; INTERP2D := INTERP2D + DELZ * FZ + DELZ * DELZ * FZZ / 2.0; INTERP3D := INTERP2D + DELZ * DELX * D2UDXDZ + DELZ * DELY * D2UDYDZ; END; BEGIN see; WRITELN('GENERATING A THREE DIMENSIONAL SPACE IN WHICH TO TEST THE '); WRITELN('INTERPOLATION ROUTINE. THIS WILL TAKE SOME TIME'); WRITELN; WRITELN(' THE FUNCTION BEING USED IS -'); WRITELN('F=SIN(X) * COS(Y) * SIN(Z) / COS(Z)'); FOR I := 0 TO 10 DO BEGIN X[I] := I; Y[I] := I; Z[I] := I; FOR K := 0 TO 10 DO FOR J := 0 TO 10 DO U[I, J, K] := SIN(I / 10.0) * COS(J / 10.0) * SIN(K / 10.0) / COS(K / 10.0); END; ERR := 0.0; FOR I := 0 TO 250 DO BEGIN YINP := I; XINP := YINP / 25.0; YINP := XINP; ZINP := YINP; UOUT := INTERP3D(XINP, YINP, ZINP, 10, 10, 10); MISTAKE := ABS(SIN(XINP / 10.0) * COS(YINP / 10.0) * SIN(ZINP / 10.0) / COS(ZINP / 10.0) - UOUT); IF (MISTAKE > ERR) THEN BEGIN WRITELN('X=', XINP : 10 : 5, ' Y=', YINP : 10 : 5, ' Z=', ZINP : 20 : 10); WRITELN(' INTERPOLATION =', UOUT : 20 : 10, ' ERROR=', MISTAKE : 20 : 10); ERR := MISTAKE; XSAVE := YINP; END; END; WRITELN('MAXIMUM ERR WAS ', ERR : 20 : 10, ' AT ', XSAVE : 20 : 10); MISTAKE := SIN(XSAVE / 10.0) * COS(XSAVE / 10.0) * SIN(XSAVE / 10.0) / COS(XSAVE / 10.0); WRITELN(' ANSWER SHOULD BE ', MISTAKE : 20 : 10); END.